<template>
  <v-autocomplete
    v-if="audtocompleted"
    :loading="isFetching"
    :items="audocompleteList"
    variant="underlined"
    @update:search="handleSearchChange"
    @update:model-value="handleModelValueChange"
    @update:focused="handleFocusedChange"
    :model-value="payload"
    clearable
    placeholder="例：徒1:1-3或林前1：3"
    color="rgb(var(--v-title))"
    base-color="rgb(var(--v-title))"
    class="text-title"
  >
    <template #item="{ item, props }">
      <v-list-item v-bind="props">
        <template #title> {{ item.title }}</template>
        <template #subtitle>
          {{ item.raw.value }}
        </template>
      </v-list-item>
    </template>
    <template #no-data>
      <div class="text-center">支持输入关键字模糊查询</div>
    </template>
    <template #clear="{ props }">
      <div class="flex items-center mt-1" v-bind="props">
        <j-icon color="rgba(var(--v-subtitle))" size="12">mdi-close</j-icon>
      </div>
    </template>
  </v-autocomplete>
  <v-text-field
    v-else
    @update:modelValue="handleSearchChange"
    :loading="isFetching"
    v-model="payload"
    label="支持输入关键字模糊查询"
  >
  </v-text-field>
</template>
<script setup>
import { useModel, shallowRef, ref, computed, watch, onMounted, onUnmounted } from "vue";

import { dist } from "@/views/SeacherSgb/dist";
import { debound } from "@/utils/utils";
import { useFeatchSearch } from "./useFeatchSearch";
const { data, error, isFetching, abort, canAbort, id, execute } = useFeatchSearch();
const emit = defineEmits(["update:modelValue", "change", "update:bibleSearchList", "onLoading"]);
const props = defineProps({
  modelValue: { type: String, default: "" },
  bibleSearchList: { type: Array, default: [] },
  audtocompleted: { type: Boolean, default: true },
});
const payload = useModel(props, "modelValue", emit);

onMounted(() => {
  if (payload.value) {
    handleSearchChange(payload.value);
  }
});
onUnmounted(() => {
  emit("update:bibleSearchList", []);
});
const numlu = (searchStr) => {
  return dist
    .map((yue) => yue.children.map((shu) => shu))
    .flat(1)
    .filter((item) => filter(item, searchStr))
    .map((item) => filterMap(item, searchStr))
    .flat(10);
};

const zmList = shallowRef([]);

const audocompleteList = computed(() => {
  return handleAutoCompleteList();
});

function handleModelValueChange(value) {
  payload.value = value;
  emit("change", value);
}

const reg1 = /([\u4e00-\u9fa5]+)(\d+)/;
const reg2 = /([\u4e00-\u9fa5]+)(\d+)[:：](\d+)-/;

const handleSearchChange = debound(async (e) => {
  const searchStr = e[0];

  if (searchStr === "") {
    clearList();
    return;
  }

  if ((searchStr.match(reg1) || searchStr.match(reg2)) && props.audtocompleted) {
    zmList.value = numlu(searchStr);
    return;
  }
  if (searchStr.length < 2) return;
  id.value = searchStr;
  if (canAbort.value) {
    abort();
  }
  if (searchStr.match(reg1) || (searchStr.match(reg2) && !props.audtocompleted)) {
    zmList.value = [searchStr];
  }
  if (!(searchStr.match(reg1) || searchStr.match(reg2)) && !props.audtocompleted) {
    zmList.value = [];
  }
  await execute();
}, 500);

function filter(item, searchStr) {
  let result = false;
  if (searchStr.match(reg2)) {
    result = _filter1(item, searchStr);
  }

  if (searchStr.match(reg1)) {
    result = filter1(item, searchStr);
  }

  return result;
}

function filter1(item, searchStr) {
  const reg = reg1;
  let match;
  if ((match = searchStr.match(reg))) {
    const [_, title, z] = match;
    if (item.title.includes(title) || item.shortTitle.includes(title)) {
      return item.children.find((cc) => cc.title == z);
    }
  }
  return null;
}
function _filter1(item, searchStr) {
  const reg = reg2;
  let execArr;
  if ((execArr = searchStr.match(reg))) {
    const [_, title, z] = execArr;
    if (item.title.includes(title) || item.shortTitle.includes(title)) {
      return item.children.find((cc) => cc.title == z);
    }
  }
  return null;
}

function filterMap(item, searchStr) {
  let match;
  if ((match = searchStr.match(reg2))) {
    const [_, t, z, j] = match;
    const result = _filter1(item, searchStr);
    const { total, title } = result;
    const { title: sTitle, shortTitle } = item;
    return [sTitle, shortTitle].map((ttitle) => {
      return [":", "："].map((smal) => {
        return Array.from({ length: total - j }).map((_, index) => `${ttitle}${z}${smal}${j}-${+j + index + 1}`);
      });
    });
  }

  if ((match = searchStr.match(reg1))) {
    const { title: sTitle, shortTitle } = item;
    const { title, total } = filter1(item, searchStr);
    return [sTitle, shortTitle].map((ttitle) => {
      return Array.from({ length: total }).map((item, index) => {
        return [":", "："].map((smal) => `${ttitle}${title}${smal}${index + 1}`);
      });
    });
  }
}

function handleFocusedChange(e) {
  if (!e) {
    clearList();
  }
}

function clearList() {
  zmList.value = [];
  data.value = [];
}

function handleAutoCompleteList() {
  const arr = [];
  // if(!payload.value){
  //   return arr;
  // }
  arr.push(
    ...zmList.value.map((item) => {
      return {
        title: item,
        value: item,
      };
    })
  );

  if (data.value) {
    const bibles = getAutoCompleteList();
    arr.push(...bibles);
  }

  return arr;
}

function getAutoCompleteList() {
  return data.value
    .map((item) => {
      const { bibles } = item;
      return bibles.map((item) => {
        const value = `${item.ShortName}${item.ChapterSN}:${item.VerseSN}`;
        let lection = item.Lection;
        const queryStrIndx = lection.indexOf(id.value);
        if (props.audtocompleted) {
          if (queryStrIndx > 20) {
            lection = item.Lection.slice(queryStrIndx);
          }
        } else {
          lection = lection.replace(
            payload.value,
            `<span style="color:rgb(var(--v-theme-primary));font-weight:500;font-size:16px;">${payload.value}</span>`
          );
        }

        return {
          title: lection,
          value: value,
        };
      });
    })
    .flat(1);
}

watch(audocompleteList, () => {
  emit("update:bibleSearchList", audocompleteList.value);
});

watch(isFetching, () => {
  emit("onLoading", isFetching);
});
</script>
<style scoped lang="less"></style>
